package com.baoyouqun.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baoyouqun.base.utils.ConvertUtils;
import com.baoyouqun.base.utils.ExcelTool;
import com.baoyouqun.domain.CreateCmd.UserSearchRecordCreateCmd;
import com.baoyouqun.domain.Query.UserSearchRecordPageQuery;
import com.baoyouqun.domain.Query.UserSearchRecordQuery;
import com.baoyouqun.domain.UpdateCmd.UserSearchRecordUpdateCmd;
import com.baoyouqun.domain.VO.KeywordFrequencyVO;
import com.baoyouqun.domain.VO.UserSearchRecordVO;
import com.baoyouqun.domain.VO.UserVO;
import com.baoyouqun.domain.VO.UserVipTimeVO;
import com.baoyouqun.entity.User;
import com.baoyouqun.entity.UserSearchRecord;
import com.baoyouqun.entity.UserVipTime;
import com.baoyouqun.mapper.UserSearchRecordMapper;
import com.baoyouqun.service.UserSearchRecordService;
import com.baoyouqun.service.UserService;
import com.baoyouqun.service.UserVipTimeService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.StringUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class UserSearchRecordServiceImpl extends ServiceImpl<UserSearchRecordMapper, UserSearchRecord> implements UserSearchRecordService {
    private static final Logger log = LoggerFactory.getLogger(UserSearchRecordServiceImpl.class);

    @Resource
    private UserSearchRecordMapper userSearchRecordMapper;

    @Resource
    private UserService userService;

    @Resource
    private UserVipTimeService userVipTimeService;

    /**
     * 创建搜索记录
     */
    @Override
    public SingleResponse<UserSearchRecordVO> create(UserSearchRecordCreateCmd cmd) {
        if (cmd == null || StringUtil.isBlank(cmd.getSearchKeyword())) {
            return SingleResponse.buildFailure("100100", "用户ID和搜索关键词不能为空");
        }

        UserSearchRecord entity = ConvertUtils.copyBean(cmd, UserSearchRecord.class);
        entity.setCreateTime(LocalDateTime.now());
        entity.setUserId(StpUtil.getLoginIdAsString());


        UserSearchRecord other = getOne(new LambdaQueryWrapper<UserSearchRecord>()
                .eq(UserSearchRecord::getUserId, entity.getUserId())
                .eq(UserSearchRecord::getSearchKeyword, entity.getSearchKeyword())
                .eq(StringUtil.isNotBlank(cmd.getType()), UserSearchRecord::getType, cmd.getType())
                .last("limit 1 ")
        );
        if (Objects.nonNull(other)) {
            other.setCreateTime(LocalDateTime.now());
            updateById(other);
            return SingleResponse.buildSuccess();
        }

        // 处理搜索类型枚举转换
        if (cmd.getSearchType() != null) {
            try {
                entity.setSearchType(cmd.getSearchType());
            } catch (IllegalArgumentException e) {
                return SingleResponse.buildFailure("100102", "无效的搜索类型");
            }
        }

        Boolean saveResult = save(entity);
        if (!saveResult) {
            return SingleResponse.buildFailure("100101", "创建搜索记录失败");
        }

        UserSearchRecordVO vo = ConvertUtils.copyBean(entity, UserSearchRecordVO.class);
        fillUserInfo(vo); // 补全用户信息
        return SingleResponse.of(vo);
    }

    /**
     * 更新搜索记录
     */
    @Override
    public Response update(UserSearchRecordUpdateCmd cmd) {
        if (cmd == null) {
            return Response.buildFailure("100301", "更新参数不能为空");
        }
        if (StringUtil.isBlank(cmd.getId())) {
            return Response.buildFailure("100302", "搜索记录ID不能为空");
        }

        UserSearchRecord oldEntity = getById(cmd.getId());
        if (oldEntity == null) {
            return Response.buildFailure("100303", "未查询到该搜索记录");
        }

        // 仅允许更新关键词和类型（不允许修改用户ID和时间）
        if (StringUtil.isNotBlank(cmd.getSearchKeyword())) {
            oldEntity.setSearchKeyword(cmd.getSearchKeyword());
        }
        if (cmd.getSearchType() != null) {
            try {
                oldEntity.setSearchType(cmd.getSearchType());
            } catch (IllegalArgumentException e) {
                return Response.buildFailure("100305", "无效的搜索类型");
            }
        }

        Boolean updateResult = updateById(oldEntity);
        return updateResult ? Response.buildSuccess() : Response.buildFailure("100304", "更新搜索记录失败");
    }

    /**
     * 根据ID查询搜索记录
     */
    @Override
    public UserSearchRecordVO selectById(String id) {
        if (StringUtil.isBlank(id)) {
            return null;
        }
        UserSearchRecord entity = userSearchRecordMapper.selectById(id);
        if (entity == null) {
            return null;
        }

        UserSearchRecordVO vo = ConvertUtils.copyBean(entity, UserSearchRecordVO.class);
        fillUserInfo(vo); // 补全用户信息
        return vo;
    }

    /**
     * 基础分页查询（旧逻辑，兼容用）
     */
    @Override
    public IPage<UserSearchRecordVO> pageVo(UserSearchRecordQuery query) {
        if (query == null) {
            query = new UserSearchRecordQuery();
        }

        IPage<UserSearchRecord> page = new Page<>(query.getCurrent() == null ? 1 : query.getCurrent(),
                query.getSize() == null ? 10 : query.getSize());

        LambdaQueryWrapper<UserSearchRecord> wrapper = new LambdaQueryWrapper<UserSearchRecord>()
                .eq(StringUtil.isNotBlank(query.getUserId()), UserSearchRecord::getUserId, query.getUserId())
                .like(StringUtil.isNotBlank(query.getType()), UserSearchRecord::getType, query.getType())
                .eq(query.getSearchType() != null, UserSearchRecord::getSearchType,
                        query.getSearchType())
                .orderByDesc(UserSearchRecord::getCreateTime);

        page = userSearchRecordMapper.selectPage(page, wrapper);
        List<UserSearchRecordVO> voList = ConvertUtils.copyBeanList(page.getRecords(), UserSearchRecordVO.class);
        voList.forEach(this::fillUserInfo); // 批量补全用户信息

        Page<UserSearchRecordVO> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        voPage.setRecords(voList);
        return voPage;
    }

    /**
     * 按条件查询关键词关联的用户记录（分页，新逻辑）
     */
    @Override
    public SingleResponse<IPage<UserSearchRecordVO>> pageUserByKeyword(UserSearchRecordPageQuery query) {
        if (query == null) {
            query = new UserSearchRecordPageQuery();
        }

        // 1. 筛选用户ID（姓名+手机号+地区）
        List<String> initialUserIdList = new ArrayList<>();
        if (StringUtil.isNotBlank(query.getName()) || StringUtil.isNotBlank(query.getCellphone()) ||
                StringUtil.isNotBlank(query.getCityCode())) {
            initialUserIdList = userService.getUserIdListByConditions(
                    query.getName(),
                    query.getCellphone(),
                    query.getCityCode()
            );

            if (CollectionUtils.isEmpty(initialUserIdList)) {
                return SingleResponse.of(emptyPage(query)); // 无用户，返回空分页
            }
        }

        // 2. 根据VIP级别筛选有效会员ID
        List<String> finalUserIdList = null;
        if (StringUtil.isNotBlank(query.getMemberLevel())) {
            finalUserIdList = userVipTimeService.getEffectiveVipUserIdList(
                    initialUserIdList,
                    query.getMemberLevel()
            );

            if (CollectionUtils.isEmpty(finalUserIdList)) {
                return SingleResponse.of(emptyPage(query)); // 无有效会员，返回空分页
            }
        } else {
            finalUserIdList = initialUserIdList; // 如果没有VIP级别筛选，直接使用初始用户ID列表
        }

        // 3. 查询搜索记录（分页）
        Long current = query.getCurrent() == null ? 1 : query.getCurrent();
        Long size = query.getSize() == null ? 10 : query.getSize();
        Page<UserSearchRecord> searchPage = new Page<>(current, size);

        LambdaQueryWrapper<UserSearchRecord> searchWrapper = new LambdaQueryWrapper<UserSearchRecord>()
                .orderByDesc(UserSearchRecord::getCreateTime);

        // 仅当有用户ID列表时才进行IN查询
        if (!CollectionUtils.isEmpty(finalUserIdList)) {
            searchWrapper.in(UserSearchRecord::getUserId, finalUserIdList);
        }

        // 搜索关键词模糊匹配
        if (StringUtil.isNotBlank(query.getSearchKeyword())) {
            searchWrapper.like(UserSearchRecord::getSearchKeyword, query.getSearchKeyword());
        }

        // 搜索类型精确匹配
        if (query.getSearchType() != null) {
            try {
                searchWrapper.eq(UserSearchRecord::getSearchType, query.getSearchType());
            } catch (IllegalArgumentException e) {
                return SingleResponse.buildFailure("100401", "无效的搜索类型");
            }
        }

        IPage<UserSearchRecord> searchResultPage = userSearchRecordMapper.selectPage(searchPage, searchWrapper);
        if (CollectionUtils.isEmpty(searchResultPage.getRecords())) {
            return SingleResponse.of(emptyPage(query)); // 无搜索记录，返回空分页
        }

        // 4. 批量补全用户信息
        // 4.1 批量查询用户基础信息（姓名、手机号、省市区）
        List<String> searchUserIdList = searchResultPage.getRecords().stream()
                .map(UserSearchRecord::getUserId)
                .distinct()
                .collect(Collectors.toList());

        LambdaQueryWrapper<User> userWrapper = new LambdaQueryWrapper<User>()
                .in(User::getId, searchUserIdList)
                .select(User::getId, User::getName, User::getCellphone,
                        User::getProvince, User::getCity, User::getDistrict);
        Map<String, User> userIdToUserMap = userService.list(userWrapper).stream()
                .collect(Collectors.toMap(User::getId, user -> user));

        // 4.2 批量查询有效会员（标记VIP）
        LambdaQueryWrapper<UserVipTime> vipWrapper = new LambdaQueryWrapper<UserVipTime>()
                .in(UserVipTime::getUserId, searchUserIdList)
                .le(UserVipTime::getStartTime, LocalDateTime.now())
                .gt(UserVipTime::getEndTime, LocalDateTime.now());
        Set<String> validVipUserIdSet = userVipTimeService.list(vipWrapper).stream()
                .map(UserVipTime::getUserId)
                .collect(Collectors.toSet());

        // 5. 转换VO并填充信息
        List<UserSearchRecordVO> voList = searchResultPage.getRecords().stream()
                .map(record -> {
                    UserSearchRecordVO vo = ConvertUtils.copyBean(record, UserSearchRecordVO.class);
                    User user = userIdToUserMap.get(record.getUserId());

                    // 填充用户基础信息
                    if (user != null) {
                        vo.setUserName(user.getName());
                        vo.setUserPhone(user.getCellphone());
                        // 拼接地区（省+市+区县）
                        String region = String.join(" ",
                                Objects.nonNull(user.getProvince()) ? user.getProvince() : "",
                                Objects.nonNull(user.getCity()) ? user.getCity() : "",
                                Objects.nonNull(user.getDistrict()) ? user.getDistrict() : ""
                        );
                        vo.setUserRegion(region.trim());
                    }

                    // 填充会员等级名称
                    vo.setMemberLevelName(validVipUserIdSet.contains(record.getUserId()) ? "VIP会员" : "临时会员");

                    // 填充搜索类型名称
                    if (record.getSearchType() != null) {
                        vo.setSearchTypeName(record.getSearchType().getName());
                    } else {
                        vo.setSearchTypeName("未知");
                    }

                    return vo;
                })
                .collect(Collectors.toList());

        // 6. 构建分页VO返回
        Page<UserSearchRecordVO> voPage = new Page<>(
                searchResultPage.getCurrent(),
                searchResultPage.getSize(),
                searchResultPage.getTotal()
        );
        voPage.setRecords(voList);

        return SingleResponse.of(voPage);
    }

    /**
     * 导出用户搜索记录Excel
     */
    @Override
    public void exportUserSearchRecords(UserSearchRecordPageQuery query, HttpServletResponse response) {
        if (query == null) {
            query = new UserSearchRecordPageQuery();
        }

        try {
            // 1. 查询所有符合条件的记录（不分页，查全部）
            query.setCurrent(1L);
            query.setSize((long) Integer.MAX_VALUE); // 最大条数（避免分页截断）
            IPage<UserSearchRecordVO> dataPage = pageUserByKeyword(query).getData();
            List<UserSearchRecordVO> dataList = dataPage.getRecords();

            // 2. 创建Excel工作簿（XLSX格式，支持大量数据）
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("用户搜索记录");
            sheet.setDefaultColumnWidth(20); // 默认列宽

            // 3. 构建表头
            String[] headers = {
                    "会员等级",
                    "姓名",
                    "手机号",
                    "所在地区",
                    "搜索/关注内容",
                    "搜索类型",
                    "搜索时间"
            };
            Row headerRow = sheet.createRow(0);
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
            }

            // 4. 填充数据行
            for (int i = 0; i < dataList.size(); i++) {
                UserSearchRecordVO vo = dataList.get(i);
                Row dataRow = sheet.createRow(i + 1); // 从第2行开始（第1行是表头）

                // 会员等级
                dataRow.createCell(0).setCellValue(Objects.nonNull(vo.getMemberLevelName()) ? vo.getMemberLevelName() : "");
                // 姓名
                dataRow.createCell(1).setCellValue(Objects.nonNull(vo.getUserName()) ? vo.getUserName() : "");
                // 手机号
                dataRow.createCell(2).setCellValue(Objects.nonNull(vo.getUserPhone()) ? vo.getUserPhone() : "");
                // 所在地区
                dataRow.createCell(3).setCellValue(Objects.nonNull(vo.getUserRegion()) ? vo.getUserRegion() : "");
                // 搜索/关注内容
                dataRow.createCell(4).setCellValue(Objects.nonNull(vo.getSearchKeyword()) ? vo.getSearchKeyword() : "");
                // 搜索类型
                dataRow.createCell(5).setCellValue(Objects.nonNull(vo.getType()) ? vo.getType() : "未知");
                // 搜索时间
                String createTimeStr = Objects.nonNull(vo.getCreateTime()) ? vo.getCreateTime().toString() : "";
                dataRow.createCell(6).setCellValue(createTimeStr);
            }

            // 5. 设置响应头（下载Excel，避免中文乱码）
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            String fileName = "用户搜索记录_" + LocalDateTime.now().toString().replace(":", "-") + ".xlsx";
            ExcelTool.setExportFileName(response, "用户搜索记录");

            response.setCharacterEncoding("UTF-8");
            response.setHeader("Pragma", "public");
            response.setHeader("Cache-Control", "max-age=30");

            // 6. 输出Excel流到响应
            try (OutputStream outputStream = response.getOutputStream()) {
                workbook.write(outputStream);
                outputStream.flush();
            } finally {
                workbook.close(); // 关闭工作簿，释放资源
            }

        } catch (IOException e) {
            log.error("导出用户搜索记录Excel失败", e);
            throw new RuntimeException("导出Excel失败：" + e.getMessage());
        } catch (Exception e) {
            log.error("导出用户搜索记录异常", e);
            throw new RuntimeException("导出Excel异常：" + e.getMessage());
        }
    }

    /**
     * 获取高频关键词（分页）
     */
    @Override
    public IPage<KeywordFrequencyVO> getHighFrequencyKeywords(Long pageSize, Long current, String keyword, Boolean isAsc) {
        // 默认分页参数
        Long page = current == null ? 1 : current;
        Long size = pageSize == null ? 10 : pageSize;
        boolean sortAsc = isAsc != null && isAsc;

        // 构建分页对象
        Page<KeywordFrequencyVO> pageObj = new Page<>(page, size);
        // 调用Mapper查询高频关键词
        Page<KeywordFrequencyVO> resultPage = userSearchRecordMapper.selectKeywordFrequencyByPage(pageObj, keyword, sortAsc);

        Page<KeywordFrequencyVO> voPage = new Page<>(page, size, resultPage.getTotal());
        voPage.setRecords(resultPage.getRecords());
        return voPage;
    }

    @Override
    public List<String> selectLatestKeywordsByUserId(String userId, int i) {
        List<UserSearchRecord> list = list(new LambdaQueryWrapper<UserSearchRecord>().eq(UserSearchRecord::getUserId, userId).last("limit " + i));
        return list.stream().distinct().map(UserSearchRecord::getSearchKeyword).collect(Collectors.toList());
    }

    // -------------------------- 工具方法 --------------------------

    /**
     * 补全用户信息（姓名、手机号、地区、会员等级）
     */
    private void fillUserInfo(UserSearchRecordVO vo) {
        if (vo == null || StringUtil.isBlank(vo.getUserId())) {
            return;
        }

        // 1. 补全用户基础信息
        UserVO user = userService.selectById(vo.getUserId());
        if (user != null) {
            vo.setUserName(user.getName());
            vo.setUserPhone(user.getCellphone());
            // 拼接地区
            String region = String.join(" ",
                    Objects.nonNull(user.getProvince()) ? user.getProvince() : "",
                    Objects.nonNull(user.getCity()) ? user.getCity() : "",
                    Objects.nonNull(user.getDistrict()) ? user.getDistrict() : ""
            );
            vo.setUserRegion(region.trim());
        }

        // 2. 补全会员等级
        UserVipTimeVO currentVip = userVipTimeService.getCurrentVip(vo.getUserId());
        vo.setMemberLevelName(currentVip != null ? "VIP会员" : "临时会员");

        // 3. 补全搜索类型名称
        if (vo.getSearchType() != null) {
            try {
                vo.setSearchTypeName(vo.getSearchType().getName());
            } catch (IllegalArgumentException e) {
                vo.setSearchTypeName("未知");
            }
        } else {
            vo.setSearchTypeName("未知");
        }
    }

    /**
     * 构建空分页（避免返回null）
     */
    private Page<UserSearchRecordVO> emptyPage(UserSearchRecordPageQuery query) {
        Long current = query.getCurrent() == null ? 1 : query.getCurrent();
        Long size = query.getSize() == null ? 10 : query.getSize();
        Page<UserSearchRecordVO> emptyPage = new Page<>(current, size, 0);
        emptyPage.setRecords(List.of());
        return emptyPage;
    }
}